import sys
import blue
import uthread
import uix
import uiutil
import xtriui
import form
import trinity
import util
import base
import math
import log
import triui
import lg
import base
import destiny
import dbg
import bluepy
import uicls
import uiconst

class SceneContainer(bluepy.WrapBlueClass('triui.UIFrame')):
    __guid__ = 'form.SceneContainer'

    def Startup(self, *args):
        self.texture = trinity.TriTexture()
        self.texture.pixels = 'res:/UI/Texture/none.dds'
        self.PrepareScene()
        self.DisplayScene()



    def PrepareScene(self):
        self.scene = trinity.Load('res:/dx9/scene/fitting/fitting.red')
        self.cameraParent = trinity.TriTransform()
        self.cameraParent.useCurves = 1
        self.cameraParent.translationCurve = trinity.EveSO2ModelCenterPos()
        self.camera = blue.os.CreateInstance('trinity.EveCamera')
        self.camera.frontClip = 1
        self.camera.fieldOfView = 1
        self.camera.parent = self.cameraParent



    def DisplayScene(self):
        self.renderJob = trinity.CreateRenderJob('SceneInScene')
        (l, t, w, h,) = self.GetAbsolute()
        self.viewport = trinity.TriViewport()
        self.viewport.x = l
        self.viewport.y = t
        self.viewport.width = w
        self.viewport.height = h
        self.viewport.minZ = 0.0
        self.viewport.maxZ = 1.0
        self.renderJob.SetViewport(self.viewport)
        self.projection = trinity.TriProjection()
        self.projection.PerspectiveFov(1.0, self.viewport.GetAspectRatio(), 1.0, 350000.0)
        self.renderJob.SetProjection(self.projection)
        self.renderJob.SetView(None, self.camera, self.cameraParent)
        self.renderJob.Update(self.scene)
        self.renderJob.RenderScene(self.scene)
        self.renderJob.ScheduleRecurring(self.scheduledRecurring)



    def SetStencilMap(self, path = 'res:/UI/Texture/circleStencil.dds'):
        stencilMap = trinity.TriTexture2DParameter()
        stencilMap.name = 'StencilMap'
        stencilMap.resourcePath = path
        self.scene.backgroundEffect.resources.append(stencilMap)
        self.scene.backgroundEffect.effectFilePath = 'res:/Graphics/Effect/Managed/Space/SpecialFX/NebulaWithStencil.fx'



    def AddToScene(self, model, clear = 1):
        if clear:
            del self.scene.objects[:]
            self.scene.objects.append(model)
        self.scene.UpdateScene(blue.os.GetTime(1))
        self.cameraParent.translationCurve.parent = model
        self.camera.rotationOfInterest.SetIdentity()



    def ClearScene(self):
        self.scene.UpdateScene(blue.os.GetTime(1))
        del self.scene.objects[:]



    def _OnResize(self, *args):
        self.UpdateViewPort()



    def UpdateViewPort(self, *args):
        (l, t, w, h,) = self.GetAbsolute()
        if ((not w) and (not h)):
            return 
        self.viewport.x = l
        self.viewport.y = t
        self.viewport.width = w
        self.viewport.height = h
        self.projection.PerspectiveFov(1.0, self.viewport.GetAspectRatio(), 1.0, 350000.0)



    def OnSetAttr(self, k, v):
        if (k in ('left', 'top', 'width', 'height')):
            self.UpdateViewPort()



    def _OnClose(self, *args):
        self.clearStep = None
        self.scene = None
        self.renderJob.UnscheduleRecurring(self.scheduledRecurring)




class SceneWindowTest(uicls.Window):
    __guid__ = 'form.SceneWindowTest'

    def ApplyAttributes(self, attributes):
        uicls.Window.ApplyAttributes(self, attributes)
        self.SetWndIcon()
        self.SetTopparentHeight(0)
        sc = form.SceneContainer(uicls.Frame(parent=self.sr.main, left=6, top=6, width=6, height=6))
        sc.Startup()
        nav = SceneContainerBaseNavigation(uicls.Container(parent=self.sr.main, left=6, top=6, width=6, height=6, idx=0, state=uiconst.UI_NORMAL))
        nav.Startup(sc)
        self.sr.navigation = nav
        self.sr.sceneContainer = sc



    def OnResizeUpdate(self, *args):
        self.sr.sceneContainer.UpdateViewPort()




class SceneContainerBaseNavigation(uicls.Container):
    __guid__ = 'form.SceneContainerBaseNavigation'

    def init(self):
        self.sr.cookie = None
        self.isTabStop = 1



    def Startup(self, sceneContainer):
        self.sr.sceneContainer = sceneContainer
        self.minZoom = 10.0
        self.maxZoom = 3000.0
        self.sr.cookie = uicore.event.RegisterForTriuiEvents(uix.UI_MOUSEUP, self._OnGlobalMouseUp)



    def _OnClose(self, *args):
        if self.sr.cookie:
            uicore.event.UnregisterForTriuiEvents(self.sr.cookie)
            self.sr.cookie = None



    def SetMinMaxZoom(self, minZoom, maxZoom):
        self.minZoom = minZoom
        self.maxZoom = maxZoom
        self.CheckCameraTranslation()



    def CheckCameraTranslation(self):
        self.sr.sceneContainer.camera.translationFromParent.z = -min(self.maxZoom, max(self.minZoom, -self.sr.sceneContainer.camera.translationFromParent.z))



    def _OnMouseWheel(self, *args):
        self.sr.sceneContainer.camera.Dolly(((-eve.triapp.uilib.dz * 0.001) * abs(self.sr.sceneContainer.camera.translationFromParent.z)))
        self.CheckCameraTranslation()



    def _OnMouseMove(self, *args):
        lib = eve.triapp.uilib
        dx = lib.dx
        dy = lib.dy
        fov = self.sr.sceneContainer.camera.fieldOfView
        cameraSpeed = 3.0
        ctrl = lib.Key(uix.VK_CONTROL)
        if (lib.rightbtn and (not lib.leftbtn)):
            self.sr.sceneContainer.camera.RotateOnOrbit(((dx * fov) * 0.2), ((-dy * fov) * 0.2))
        if (lib.leftbtn and (not lib.rightbtn)):
            self.sr.sceneContainer.camera.OrbitParent((((dx * fov) * 0.2) * cameraSpeed), (((-dy * fov) * 0.2) * cameraSpeed))
        if (lib.leftbtn and lib.rightbtn):
            self.sr.sceneContainer.camera.Dolly(((dy * 0.01) * abs(self.sr.sceneContainer.camera.translationFromParent.z)))
            self.CheckCameraTranslation()
            if ctrl:
                self.sr.sceneContainer.camera.fieldOfView = ((-dx * 0.01) + fov)
                if (self.sr.sceneContainer.camera.fieldOfView > 1.0):
                    self.sr.sceneContainer.camera.fieldOfView = 1.0
                if (self.sr.sceneContainer.camera.fieldOfView < 0.1):
                    self.sr.sceneContainer.camera.fieldOfView = 0.1
            else:
                self.sr.sceneContainer.camera.OrbitParent(((dx * fov) * 0.2), 0.0)



    def _OnGlobalMouseUp(self, wnd, msgID, btn, *args):
        if (btn and (btn[0] == 1)):
            self.sr.sceneContainer.camera.rotationOfInterest.SetIdentity()
        return 1




